package com.java.synchronized_;

/**
 * 同步方法解决线程安全问题
 */
public class SynchronizedMethod {
    static class ThreadSon extends Thread {
        // static修饰是因为票的数量应该被所有窗口共享
        static int ticket = 0;
        
        @Override
        public void run() {
            while (true) { // while不能在同步代码块内部，否则票将由同一窗口卖
                if (extracted()) {break;}
            }
        }
        
        // static修饰是因为锁对象需为当前类的Class对象，即钥匙是同一把。如果不是static则锁对象为this，仍然出现重复卖或卖超的问题，即钥匙不是同一把
        private static synchronized boolean extracted() { // 同步方法⭐⭐⭐
            if (ticket > 9) {
                return true;
            }
            
            try {
                Thread.sleep(10); // 模拟窗口出票延时
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            
            ticket++;
            System.out.println(Thread.currentThread().getName() + "正在卖第" + ticket + "张票");
            return false;
        }
    }
    
    public static void main(String[] args) throws InterruptedException {
        new ThreadSon().start();
        new ThreadSon().start();
        new ThreadSon().start();
    }
    
    /**
     * 输出结果如下，每次运行的结果不同！未出现重复卖或卖超的问题
     * Thread-0正在卖第1张票
     * Thread-2正在卖第2张票
     * Thread-1正在卖第3张票
     * Thread-1正在卖第4张票
     * Thread-0正在卖第5张票
     * Thread-2正在卖第6张票
     * Thread-2正在卖第7张票
     * Thread-0正在卖第8张票
     * Thread-1正在卖第9张票
     * Thread-0正在卖第10张票
     */
}
